package com.th.supcom.pds.common.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.carefx.fc.framework.web.gwt.util.FcConstants;
import net.carefx.framework.container.client.context.AppContext;
import net.carefx.framework.container.client.model.EmpModel;
import net.carefx.framework.container.client.model.OrgModel;
import net.carefx.framework.container.client.model.UserModel;
import net.carefx.framework.container.client.model.WorkbenchModel;

import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.util.KeyNav;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.MessageBox.MessageBoxType;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.google.gwt.i18n.client.NumberFormat;
import com.th.supcom.pds.common.client.commom.SimpleMethod;
import com.th.supcom.pds.common.client.model.CodeConstants;
import com.th.supcom.pds.common.constant.KeysConstants;
import com.th.supcom.pds.common.enums.AvailableEnum;
import com.th.supcom.pds.common.enums.StockEnoughEnum;
import com.th.supcom.pds.phamapply.client.model.InpPhamApplyDetailModel;
import com.th.supcom.pds.phamapply.client.model.InpPhamApplyDetailSummaryModel;
import com.th.supcom.pds.sortingdrug.client.model.PdsPrescDetailInfoModel;

public final class ClientUtils
{
    //员工信息
    private static EmpModel s_empModel = AppContext.get ().getCurrentUser ().getEmpModel ();
    private static WorkbenchModel s_workbenchModel = AppContext.get ().get (FcConstants.CURRENT_SELECTED_WORKBENCH);
    //所在机构信息
    private static OrgModel s_orgModel = s_workbenchModel.getOrgModel (); 

    /**
     * 获取平台用户信息
     * 
     * @return
     */
    public static final EmpModel geteEmpModel ()
    {
        
        return s_empModel;
    }

    /**
     * 获取平台用户组织机构
     * 
     * @return
     */
    public static OrgModel getOrgModel ()
    {
        return s_orgModel;
    }

    /**
     * 渲染数字的列 1.数字向右对齐 2.金额 (costs)保留两位小数
     * 
     * @param str 列名
     * @return
     */
    public static GridCellRenderer <ModelData> renderForNumber (final String str)
    {
        return new GridCellRenderer <ModelData> ()
        {

            @Override
            public Object render (ModelData model, String property, ColumnData config, int rowIndex, int colIndex, ListStore <ModelData> store, Grid <ModelData> grid)
            {
                String columnValue = str;
                final NumberFormat m_number = NumberFormat.getFormat ("0.00");
                if (model.get (str) == null)
                {
                    return "<span></span>";
                }
                if (model.get (str) instanceof Double)
                {
                    Double colDate = Math.abs ((Double) model.get (str));
                    columnValue = "costs".equals (columnValue) ? m_number.format (colDate) : colDate.toString ();
                }

                if (model.get (str) instanceof Integer)
                {
                    Integer colDate = Math.abs ((Integer) model.get (str));
                    columnValue = "costs".equals (columnValue) ? m_number.format (colDate) : colDate.toString ();
                }

                return "<span style='float:right'>" + columnValue + "</span>";
            }

        };
    }

    /**
     * @param collection
     * @return
     */
    public static boolean isEmpty (Collection < ? > collection)
    {
        return collection == null || collection.size () == 0;
    }

    /**
     * 为面板添加全局的快捷键
     * 
     * @param component
     * @param map 存放快捷键码和对应的事件 add by Zli
     */
    public static void addBlobalShortKey (final Component component, final Map <Integer, EventType> map)
    {
        new KeyNav <ComponentEvent> (component)
        {
            @Override
            public void onKeyPress (final ComponentEvent ce)
            {
                final int keyCode = ce.getKeyCode ();

                if (ce.isAltKey ())
                {

                    for (final Integer key : map.keySet ())
                    {
                        if (keyCode == key)
                        {
                            final AppEvent event = new AppEvent (map.get (key));
                            Dispatcher.forwardEvent (event);
                            return;
                        }
                    }
                }
            }
        };
    }

    /**
     * 失败时弹出对话框并将焦点返回到focusComponent对象上
     * 
     * @param message
     * @param focusComponent
     */
    public static void alertMessageBox (final String message, final Component focusComponent)
    {
        MessageBox.alert (CodeConstants.PROMPT, message, new Listener <MessageBoxEvent> ()
        {

            @Override
            public void handleEvent (final MessageBoxEvent be)
            {
                if (null != focusComponent)
                {
                    focusComponent.focus ();
                }
            }
        });
    }

    /**
     * 转化null 为""
     * 
     * @param str
     * @return add by Zli
     */
    public static String avoidNull (final Object str)
    {
        return str == null ? "" : str + "";
    }

    /**
     * 
     * @param title
     * @param type
     * @return add by Zli
     */
    public static Button createButton (final String title, final EventType type)
    {
        final Button btnButton = new Button (title);
        btnButton.setWidth (80);
        btnButton.addSelectionListener (new SelectionListener <ButtonEvent> ()
        {

            @Override
            public void componentSelected (final ButtonEvent ce)
            {
                final AppEvent event = new AppEvent (type);
                Dispatcher.forwardEvent (event);
            }
        });

        return btnButton;
    }

    /**
     * 设置序号列Renderer,每组排序序号从1开始
     * 
     * @param groupProperty 分组属性
     * @return
     */
    public static GridCellRenderer <ModelData> createRowNumberRenderer (final String groupProperty)
    {

        return new GridCellRenderer <ModelData> ()
        {
            private Map <String, Integer> m_propertyMap = new HashMap <String, Integer> ();

            @Override
            public Object render (final ModelData model, final String property, final ColumnData config, final int rowIndex, final int colIndex, final ListStore <ModelData> store,
                                  final Grid <ModelData> grid)
            {
                if (0 == rowIndex)
                {
                    m_propertyMap = new HashMap <String, Integer> ();
                }

                config.cellAttr = "rowspan='2'";
                final String groupValue = model.get (groupProperty);

                if (null == groupValue)
                {
                    return null;
                }

                if (!m_propertyMap.containsKey (groupValue))
                {
                    m_propertyMap.put (groupValue, rowIndex);
                }

                if (m_propertyMap.containsKey (groupValue))
                {
                    return String.valueOf (rowIndex - m_propertyMap.get (groupValue) + 1);
                }

                return null;
            }
        };
    }

    /**
     * 前台格式化double类型为String类型，保留两位有效数字
     * 
     * @return
     */
    public static String formatNumTwo (final Double value)
    {
        final NumberFormat number = NumberFormat.getFormat ("0.00");
        return number.format (value);
    }

    /**
     * 左右键改变光标位置
     * 
     * @param prev 前一个按钮
     * @param next 后一个按钮
     * @param component 触发按钮
     */
    public static void getFocusChange (final Component prev, final Component next, final Component component)
    {
        new KeyNav <ComponentEvent> (component)
        {
            @Override
            public void onKeyPress (final ComponentEvent ce)
            {
                final int keyCode = ce.getKeyCode ();
                if (keyCode == KeysConstants.KEY_RIGHT && next != null)
                {
                    next.focus ();
                }
                else if (keyCode == KeysConstants.KEY_LEFT && prev != null)
                {
                    prev.focus ();
                }
            }
        };
    }

    /**
     * 获得选中处方对应的所有处方明细记录
     * 
     * @param prescLists
     * @param prescDetailList
     * @return
     */
    public static List <PdsPrescDetailInfoModel> getPrescDetailSelected (final List <PdsPrescDetailInfoModel> prescLists, final List <PdsPrescDetailInfoModel> prescDetailList)
    {
        final List <PdsPrescDetailInfoModel> prescDetailListSelected = new ArrayList <PdsPrescDetailInfoModel> ();
        // 获取勾选处方明细记录
        for (final PdsPrescDetailInfoModel prescModel : prescLists)
        {
            for (final PdsPrescDetailInfoModel prescDetailmodel : prescDetailList)
            {
                if (prescDetailmodel.getPrescNo ().equals (prescModel.getPrescNo ()))
                {
                    prescDetailListSelected.add (prescDetailmodel);
                }
            }
        }
        return prescDetailListSelected;
    }

    /**
     * 浮点数靠右对齐
     * 
     * @param str
     * @return
     */
    public static final GridCellRenderer <ModelData> getRenderer (final String str)
    {
        final GridCellRenderer <ModelData> change = new GridCellRenderer <ModelData> ()
        {
            final NumberFormat m_number = NumberFormat.getFormat ("0.00");

            @Override
            public Object render (final ModelData model, final String property, final ColumnData config, final int rowIndex, final int colIndex, final ListStore <ModelData> store,
                                  final Grid <ModelData> grid)
            {
                if (model.get (str) == null)
                {
                    return "<span></span>";
                }
                final Object value = model.get (str) instanceof Integer ? model.get (str) : m_number.format ((Double) model.get (str));
                return "<span style='float:right'>" + value.toString () + "</span>";
            }
        };
        return change;
    }

    /**
     * 服法渲染器
     * 
     * @return
     */
    public static GridCellRenderer <ModelData> createUsageRenderer ()
    {
        return new GridCellRenderer <ModelData> ()
        {

            @Override
            public Object render (final ModelData model, final String property, final ColumnData config, final int rowIndex, final int colIndex, final ListStore <ModelData> store,
                                  final Grid <ModelData> grid)
            {
                if (model == null)
                {
                    return "";
                }
                String dosePerUnit = "";
                String perMedQty = model.get ("perMedQty");
                String[] perMedQtys = perMedQty.split (",");
                for (int i = 0; i < perMedQtys.length; i++)
                {
                    String flag = i + 1 == perMedQtys.length ? "" : ",";
                    dosePerUnit +=SimpleMethod.retainDoubleTwo(Double.parseDouble (perMedQtys[i]) / (Double) model.get ("dosePerUnit") )+ avoidNull (model.get ("qtyUnitName")) + flag;
                }
                String qtyUnitName = "(" + avoidNull (avoidNull (dosePerUnit) + ")");
                return "<span>" + avoidNull (model.get ("freqCodeName")) + " 每次" + avoidNull (model.get ("perMedQty")) + avoidNull (model.get ("medUnitName")) + qtyUnitName + "</span>";
            }
        };
    }

    /**
     * Displays a message box with OK and Cancel buttons prompting the user to
     * enter some text (comparable to JavaScript's prompt).
     * 
     * @param title the title bar text
     * @param msg the message box body text
     * @param multiline true for a multi-line text aread
     * @return the new message box
     */
    public static MessageBox prompt (final String title, final String value, final String msg, final boolean multiline, final Listener <MessageBoxEvent> callback)
    {
        final MessageBox box = new MessageBox ();
        box.setTitle (title);
        box.setMessage (msg);
        box.setType (MessageBoxType.PROMPT);
        box.setButtons (Dialog.OKCANCEL);
        box.setType (multiline ? MessageBoxType.MULTIPROMPT : MessageBoxType.PROMPT);
        if (callback != null)
        {
            box.addCallback (callback);
        }
        box.getTextBox ().setValue (value);
        box.show ();
        return box;
    }

    // public static List <T> voToModelConvert (List <T> list, Class clazz)
    // {
    // // 将vo转化为model自定义模式
    // if (list.isEmpty ())
    // {
    // return new ArrayList <T> ();
    // }
    // Mapper mapper = new DozerBeanMapper ();
    // List <T> result = new ArrayList <T> ();
    // for (T vo : list)
    // {
    // result.add (mapper.map (vo, clazz));
    // }
    // return result;
    // }

    private ClientUtils ()
    {

    }

    /**
     * 验证组件是否为空
     * 
     * @param fields
     * @param messges
     * @return
     */

    public static boolean validateFields (List <TextField < ? >> fields, List <String> messges)
    {
        for (int i = 0; i < fields.size (); i++)
        {
            if (null == fields.get (i).getValue ())
            {
                MessageBox.alert (CodeConstants.PROMPT, messges.get (i), null);
                return false;
            }
        }

        return true;

    }
    /**
     * 获取库存充足标识的Renderer
     * 
     * @return
     */
    public static GridCellRenderer <InpPhamApplyDetailModel> getStockEnoughRenderer ()
    {
        return new GridCellRenderer <InpPhamApplyDetailModel> ()
        {

            @Override
            public Object render (InpPhamApplyDetailModel model, String property, ColumnData config, int rowIndex, int colIndex, ListStore <InpPhamApplyDetailModel> store,
                                  Grid <InpPhamApplyDetailModel> grid)
            {
                if (model.getApplySupplyFlag () != null && AvailableEnum.NO.getEnumCode ().equals (model.getApplySupplyFlag ()))
                {
                    return "<div style='background-color:yellow;height:16px' title='药品不可供'></div>";
                }

                if (model.getStockEnoughFlag () != null && StockEnoughEnum.NO.getEnumCode ().equals (model.getStockEnoughFlag ()))
                {
                    return "<div style='background-color:red;height:16px' title='药品库存不足'></div>";
                }

                if (model.getArreas ())
                {
                    return "<div style='background-color:green;height:16px' title='患者欠费'></div>";
                }

                return "";
            }
        };
    }

    /**
     * 获取库存充足标识的Renderer
     * 
     * @return
     */
    public static GridCellRenderer <InpPhamApplyDetailSummaryModel> getSummaryStockEnoughRenderer ()
    {
        return new GridCellRenderer <InpPhamApplyDetailSummaryModel> ()
        {

            @Override
            public Object render (InpPhamApplyDetailSummaryModel model, String property, ColumnData config, int rowIndex, int colIndex, ListStore <InpPhamApplyDetailSummaryModel> store,
                                  Grid <InpPhamApplyDetailSummaryModel> grid)
            {
                if (model.getApplySupplyFlag () != null && AvailableEnum.NO.getEnumCode ().equals (model.getApplySupplyFlag ()))
                {
                    return "<div style='background-color:yellow;height:16px' title='药品不可供'></div>";
                }

                if (model.getStockEnoughFlag () != null && StockEnoughEnum.NO.getEnumCode ().equals (model.getStockEnoughFlag ()))
                {
                    return "<div style='background-color:red;height:16px' title='药品库存不足'></div>";
                }

                return "";
            }
        };
    }

    /** 提交路径. */
    public static final String SCC_BRANCH = "$URL$";

    /** 提交日期. */
    public static final String SCC_LAST_MODIFICATION_DATE = "$Date$";

    /** 最终修改人员. */
    public static final String SCC_LAST_MODIFIER_NAME = "$Author$";

    /** 最终版本号. */
    public static final String SCC_REVISION = "$Revision$";
}
